{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# super() 函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "    super(CurrentClassName, instance)\n",
    "    \n",
    "返回该类实例对应的父类对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Leaf(object):\n",
    "    def __init__(self, color=\"green\"):\n",
    "        self.color = color\n",
    "    def fall(self):\n",
    "        print \"Splat!\"\n",
    "\n",
    "class MapleLeaf(Leaf):\n",
    "    def change_color(self):\n",
    "        if self.color == \"green\":\n",
    "            self.color = \"red\"\n",
    "    def fall(self):\n",
    "        self.change_color()\n",
    "        super(MapleLeaf, self).fall()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里，我们先改变树叶的颜色，然后再找到这个实例对应的父类，并调用父类的 `fall()` 方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "green\n",
      "Splat!\n",
      "red\n"
     ]
    }
   ],
   "source": [
    "mleaf = MapleLeaf()\n",
    "\n",
    "print mleaf.color\n",
    "mleaf.fall()\n",
    "print mleaf.color"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "回到我们的森林例子，这里我们将森林 `Forest` 作为父类，并定义一个子类 `BurnableForest`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "class Forest(object):\n",
    "    \"\"\" Forest can grow trees which eventually die.\"\"\"\n",
    "    def __init__(self, size=(150,150), p_sapling=0.0025):\n",
    "        self.size = size\n",
    "        self.trees = np.zeros(self.size, dtype=bool)\n",
    "        self.p_sapling = p_sapling\n",
    "        \n",
    "    def __repr__(self):\n",
    "        my_repr = \"{}(size={})\".format(self.__class__.__name__, self.size)\n",
    "        return my_repr\n",
    "    \n",
    "    def __str__(self):\n",
    "        return self.__class__.__name__\n",
    "    \n",
    "    @property\n",
    "    def num_cells(self):\n",
    "        \"\"\"Number of cells available for growing trees\"\"\"\n",
    "        return np.prod(self.size)\n",
    "    \n",
    "    @property\n",
    "    def tree_fraction(self):\n",
    "        \"\"\"\n",
    "        Fraction of trees\n",
    "        \"\"\"\n",
    "        num_trees = self.trees.sum()\n",
    "        return float(num_trees) / self.num_cells\n",
    "    \n",
    "    def _rand_bool(self, p):\n",
    "        \"\"\"\n",
    "        Random boolean distributed according to p, less than p will be True\n",
    "        \"\"\"\n",
    "        return np.random.uniform(size=self.trees.shape) < p\n",
    "    \n",
    "    def grow_trees(self):\n",
    "        \"\"\"\n",
    "        Growing trees.\n",
    "        \"\"\"\n",
    "        growth_sites = self._rand_bool(self.p_sapling)\n",
    "        self.trees[growth_sites] = True    \n",
    "        \n",
    "    def advance_one_step(self):\n",
    "        \"\"\"\n",
    "        Advance one step\n",
    "        \"\"\"\n",
    "        self.grow_trees()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 将与燃烧相关的属性都被转移到了子类中去。\n",
    "- 修改两类的构造方法，将闪电概率放到子类的构造方法上，同时在子类的构造方法中，用 `super` 调用父类的构造方法。\n",
    "- 修改 `advance_one_step()`，父类中只进行生长，在子类中用 `super` 调用父类的 `advance_one_step()` 方法，并添加燃烧的部分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class BurnableForest(Forest):\n",
    "    \"\"\"\n",
    "    Burnable forest support fires\n",
    "    \"\"\"    \n",
    "    def __init__(self, p_lightning=5.0e-6, **kwargs):\n",
    "        super(BurnableForest, self).__init__(**kwargs)\n",
    "        self.p_lightning = p_lightning        \n",
    "        self.fires = np.zeros((self.size), dtype=bool)\n",
    "    \n",
    "    def advance_one_step(self):\n",
    "        \"\"\"\n",
    "        Advance one step\n",
    "        \"\"\"\n",
    "        super(BurnableForest, self).advance_one_step()\n",
    "        self.start_fires()\n",
    "        self.burn_trees()\n",
    "        \n",
    "    @property\n",
    "    def fire_fraction(self):\n",
    "        \"\"\"\n",
    "        Fraction of fires\n",
    "        \"\"\"\n",
    "        num_fires = self.fires.sum()\n",
    "        return float(num_fires) / self.num_cells\n",
    "    \n",
    "    def start_fires(self):\n",
    "        \"\"\"\n",
    "        Start of fire.\n",
    "        \"\"\"\n",
    "        lightning_strikes = (self._rand_bool(self.p_lightning) & \n",
    "            self.trees)\n",
    "        self.fires[lightning_strikes] = True\n",
    "        \n",
    "    def burn_trees(self):\n",
    "        \"\"\"\n",
    "        Burn trees.\n",
    "        \"\"\"\n",
    "        fires = np.zeros((self.size[0] + 2, self.size[1] + 2), dtype=bool)\n",
    "        fires[1:-1, 1:-1] = self.fires\n",
    "        north = fires[:-2, 1:-1]\n",
    "        south = fires[2:, 1:-1]\n",
    "        east = fires[1:-1, :-2]\n",
    "        west = fires[1:-1, 2:]\n",
    "        new_fires = (north | south | east | west) & self.trees\n",
    "        self.trees[self.fires] = False\n",
    "        self.fires = new_fires"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试父类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.00284444444444\n"
     ]
    }
   ],
   "source": [
    "forest = Forest()\n",
    "\n",
    "forest.grow_trees()\n",
    "\n",
    "print forest.tree_fraction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试子类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "burnable_forest = BurnableForest()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "调用自己和父类的方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.00235555555556\n"
     ]
    }
   ],
   "source": [
    "burnable_forest.grow_trees()\n",
    "burnable_forest.start_fires()\n",
    "burnable_forest.burn_trees()\n",
    "print burnable_forest.tree_fraction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "查看变化："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x3ca1ef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "forest = Forest()\n",
    "forest2 = BurnableForest()\n",
    "\n",
    "tree_fractions = []\n",
    "\n",
    "for i in range(2500):\n",
    "    forest.advance_one_step()\n",
    "    forest2.advance_one_step()\n",
    "    tree_fractions.append((forest.tree_fraction, forest2.tree_fraction))\n",
    "\n",
    "plt.plot(tree_fractions)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`__str__` 和 `__repr__` 中 `self.__class__` 会根据类型不同而不同："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Forest(size=(150, 150))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "BurnableForest(size=(150, 150))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forest2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Forest\n"
     ]
    }
   ],
   "source": [
    "print forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BurnableForest\n"
     ]
    }
   ],
   "source": [
    "print forest2"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
